package cn.anecansaitin.industrialization_expansion.common.cap;

import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.energy.IEnergyStorage;

/*
 * nbt结构
 *   nbt
 *    └ cap
 *       └ energy
 *          ├ energy (int)
 *          ├ capacity (int)
 *          ├ max_extract (int)
 *          └ max_receive (int)
 * */
public class ItemEnergyStorage implements IEnergyStorage {
    private final ItemStack stack;

    public ItemEnergyStorage(ItemStack stack) {
        this.stack = stack;
    }

    @Override
    public int receiveEnergy(int maxReceive, boolean simulate) {
        if (!canReceive())
            return 0;

        int capacity = getMaxEnergyStored();
        int energy = getEnergyStored();
        int receive = getMaxReceive();

        int energyReceived = Math.min(capacity - energy, Math.min(receive, maxReceive));

        if (!simulate) {
            energy += energyReceived;
            getCapNBT().putInt("energy", energy);
        }

        return energyReceived;
    }

    @Override
    public int extractEnergy(int maxExtract, boolean simulate) {
        if (!canExtract())
            return 0;

        int energy = getEnergyStored();
        int extract = getMaxExtract();

        int energyExtracted = Math.min(energy, Math.min(extract, maxExtract));

        if (!simulate) {
            energy -= energyExtracted;
            getCapNBT().putInt("energy", energy);
        }

        return energyExtracted;
    }

    @Override
    public int getEnergyStored() {
        int energy;
        CompoundNBT nbt = getCapNBT();

        if (nbt.contains("energy"))
            energy = nbt.getInt("energy");
        else energy = 0;

        return energy;
    }

    @Override
    public int getMaxEnergyStored() {
        int capacity;
        CompoundNBT nbt = getCapNBT();

        if (nbt.contains("capacity"))
            capacity = nbt.getInt("capacity");
        else capacity = 0;

        return capacity;
    }

    @Override
    public boolean canExtract() {
        return getMaxExtract() > 0;
    }

    @Override
    public boolean canReceive() {
        return getMaxReceive() > 0;
    }

    protected int getMaxReceive(){
        int maxReceive;
        CompoundNBT nbt = getCapNBT();

        if (nbt.contains("max_receive"))
            maxReceive = nbt.getInt("max_receive");
        else maxReceive = 0;

        return maxReceive;
    }

    protected int getMaxExtract() {
        CompoundNBT nbt = getCapNBT();
        int maxExtract;

        if (nbt.contains("max_extract"))
            maxExtract = nbt.getInt("max_extract");
        else maxExtract = 0;

        return maxExtract;
    }

    public void format(int capacity, int maxReceive, int maxExtract, int energy) {
        CompoundNBT nbt = getCapNBT();
        nbt.putInt("capacity", capacity);
        nbt.putInt("max_receive", maxReceive);
        nbt.putInt("max_extract", maxExtract);
        nbt.putInt("energy", energy);
    }

    private CompoundNBT getCapNBT() {
        CompoundNBT cap = stack.getOrCreateTagElement("cap");

        if (cap.contains("energy"))
            return cap.getCompound("energy");
        else {
            CompoundNBT compoundNBT = new CompoundNBT();
            cap.put("energy", compoundNBT);
            return compoundNBT;
        }
    }
}
